#include "parser.h"
#include "../input/input.h"

void create_tree(int l,int kiri,int kanan,address X) {
    while (Line[l][kiri] == ' ') ++kiri;
    while (Line[l][kanan] == ' ') --kanan;
    int i;
    
    if (Line[l][kiri] == '(') {
        int first = kiri,last = kiri;
        int nob = 1;

        for (i=kiri+1;i<=kanan;++i) {
            if (Line[l][i] == ')') {
                --nob;
                if (!nob) last = i;
            } else if (Line[l][i] == '(') {
                ++nob;
                if (nob == 1) first = i;
            }
        }
        
        if ((first == kiri)&&(last == kanan)) {
            ++kiri;
            --kanan;
            while (Line[l][kiri] == ' ') ++kiri;
            while (Line[l][kanan] == ' ') --kanan;
        }
    }
    
    int implikasi = -1;
    int disjungsi = -1;
    int konjungsi = -1;
    int nob = 0;
    Isi(X) = NULL;
    
    for (i=kiri;i<=kanan;++i) {
        if (Line[l][i] == '(') {
            ++nob;
        } else if (Line[l][i] == ')') {
            --nob;
        }
        
        if (!nob) {
            if (Line[l][i] == '-') {
                if (Line[l][i-1] == '<') implikasi = i-1;
                else if (Line[l][i+1] == '>') implikasi = i;
            } else if (Line[l][i] == '|') {
                disjungsi = i;
            } else if (Line[l][i] == '&') {
                konjungsi = i;
            }
        }
    }
    
    if (implikasi > -1) {
        int akhir;
        if (Line[l][implikasi] == '<' && Line[l][implikasi+2] == '>') {
            Operator(X) = '=';
            akhir = implikasi+3;
            printf("equivalence (");
			WriteLine("equivalence (");
        } else if (Line[l][implikasi] == '<') {
            Operator(X) = '<';
            akhir = implikasi+2;
            printf("reduction (");
			WriteLine("reduction (");
        } else {
            Operator(X) = '>';
            akhir = implikasi+2;
            printf("implication (");
			WriteLine("implication (");
        }

        Left(X) = malloc(sizeof(node));
        Right(X) = malloc(sizeof(node));
        
        create_tree(l, kiri, implikasi-1, Left(X));
        printf(" , ");
		WriteLine(" , ");
        create_tree(l, akhir, kanan, Right(X));
        printf(")");
		WriteLine(")");
    } else if (disjungsi > -1) {
        Operator(X) = '|';
        Left(X) = malloc(sizeof(node));
        Right(X) = malloc(sizeof(node));
        
        printf("disjunction (");
		WriteLine("disjunction (");
        create_tree(l, kiri, disjungsi-1, Left(X));
        printf(" , ");
		WriteLine(" , ");
        create_tree(l, disjungsi+1, kanan, Right(X));
        printf(")");
		WriteLine(")");
    } else if (konjungsi > -1) {
        Operator(X) = '&';
        Left(X) = malloc(sizeof(node));
        Right(X) = malloc(sizeof(node));
        
        printf("conjunction (");
		WriteLine("conjunction (");
        create_tree(l, kiri, konjungsi-1, Left(X));
        printf(" , ");
		WriteLine(" , ");
        create_tree(l, konjungsi+1, kanan, Right(X));  
        printf(")");
		WriteLine(")");
    } else {
        if (Line[l][kiri] == '-') {
            Operator(X) = '-';
            
            printf("negation (");
			WriteLine("negation (");
            Left(X) = malloc(sizeof(node));
            create_tree(l, kiri+1, kanan, Left(X));  
            Right(X) = NULL;
            printf(")");
			WriteLine(")");
        } else if (!strncmp(Line[l]+kiri,"all",3)) {
            Operator(X) = 'a';
            kiri += 3;
            while (Line[l][kiri] == ' ') ++kiri;
            int sem = kiri;
            
            while ((Line[l][sem] != '(')&&(Line[l][sem] != ' ')){
                ++sem;
            }
            
            Isi(X) = malloc(sem-kiri+1);
            strncpy(Isi(X),Line[l]+kiri,sem-kiri);
            Isi(X)[sem-kiri] = 0;
            
            boolean ada = true;
            int i;
            for (i=0;i<tvar && ada;++i) {
                ada = (strcmp(variable[i],Isi(X)) != 0);
            }
            
            if (ada) {
                variable[tvar] = malloc(sem-kiri+1);
                strcpy(variable[tvar], Isi(X));
                ++tvar;
            }
            
            printf("all %s (",Isi(X));
			WriteLine("all ");
			WriteLine(Isi(X));
			WriteLine(" (");
            Left(X) = malloc(sizeof(node));
            create_tree(l,sem,kanan,Left(X));
            Right(X) = NULL;
            printf(")");
			WriteLine(")");
        } else if (!strncmp(Line[l]+kiri,"exists",6)) {
            Operator(X) = 'e';
            kiri += 6;
            while (Line[l][kiri] == ' ') ++kiri;
            int sem = kiri;
            
            while ((Line[l][sem] != '(')&&(Line[l][sem] != ' ')){
                ++sem;
            }
            
            Isi(X) = malloc(sem-kiri+1);
            strncpy(Isi(X),Line[l]+kiri,sem-kiri);
            Isi(X)[sem-kiri] = 0;

            boolean ada = true;
            int i;
            for (i=0;i<tvar && ada;++i) {
                ada = (strcmp(variable[i],Isi(X)) != 0);
            }
            
            if (ada) {
                variable[tvar] = malloc(sem-kiri+1);
                strcpy(variable[tvar], Isi(X));
                ++tvar;
            }            
            
            printf("exists %s (",Isi(X));
			WriteLine("exists ");
			WriteLine(Isi(X));
			WriteLine(" (");
            Left(X) = malloc(sizeof(node));
            create_tree(l,sem,kanan,Left(X));
            Right(X) = NULL;
            printf(")");
			WriteLine(")");
        } else {
            Operator(X) = 'f';
            Isi(X) = malloc(kanan-kiri+2);
            strncpy(Isi(X),Line[l]+kiri,kanan-kiri+1);
            Isi(X)[kanan-kiri+1] = 0;
            Left(X) = Right(X) = NULL;
            printf("term %s",Isi(X));
			WriteLine("term ");
			WriteLine(Isi(X));
        }
    }
}

void parse_premise() {
    int i = 1;
    while (strcmp(Line[i], "end_of_dream.")) {
        printf("\npremis %d\n",i);
		WriteLine("(");
		WriteInt(index);
		WriteLine(") ");
		index++;
        premis[i] = malloc(sizeof(node));
        create_tree(i,0,strlen(Line[i])-2,premis[i]);
        printf("\n");
		WriteLine(" [premise]\n");
        ++i;
    }
    tpremis = i-1;
}

void parse_goal() {
    int i=1;
    while (strcmp(Line[i], "formulate(destiny).")) ++i;
    
    ++i;
    tgoal = 0;
    while (strcmp(Line[i], "end_of_destiny.")) {
        ++tgoal;
        printf("\nnegated goal %d\n",tgoal);
		WriteLine("(");
		WriteInt(index);
		WriteLine(") ");
		index++;
        ngoal[tgoal] = malloc(sizeof(node));
        Operator(ngoal[tgoal]) = '-';   
        printf("negation (");
        Left(ngoal[tgoal]) = malloc(sizeof(node));
        create_tree(i,0,strlen(Line[i])-2,Left(ngoal[tgoal]));
        printf(")");
        printf("\n");
		WriteLine(" [goal]\n");
        ++i;
    }
}
